/**
 * 日期时间工具函数
 * 提供常用的日期时间格式化、计算等功能
 */

/**
 * 日期格式化
 * @param {Date|string|number} date - 日期对象、时间戳或日期字符串
 * @param {string} [format='YYYY-MM-DD HH:mm:ss'] - 格式化模板
 * @returns {string} 格式化后的日期字符串
 * 
 * 支持的格式：
 * - YYYY: 四位年份
 * - MM: 两位月份
 * - M: 月份，不补零
 * - DD: 两位日期
 * - D: 日期，不补零
 * - HH: 两位小时（24小时制）
 * - H: 小时，不补零（24小时制）
 * - hh: 两位小时（12小时制）
 * - h: 小时，不补零（12小时制）
 * - mm: 两位分钟
 * - m: 分钟，不补零
 * - ss: 两位秒数
 * - s: 秒数，不补零
 * - SSS: 毫秒
 * - A: AM/PM
 * - a: am/pm
 */
export function formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
  if (!date) return '';
  
  const d = typeof date === 'object' 
    ? date 
    : new Date(date);
  
  if (isNaN(d.getTime())) return '';
  
  const o = {
    'M+': d.getMonth() + 1, // 月份
    'D+': d.getDate(), // 日
    'H+': d.getHours(), // 小时
    'h+': d.getHours() % 12 || 12, // 12小时制
    'm+': d.getMinutes(), // 分
    's+': d.getSeconds(), // 秒
    'S+': d.getMilliseconds(), // 毫秒
    'A': d.getHours() < 12 ? 'AM' : 'PM', // AM/PM
    'a': d.getHours() < 12 ? 'am' : 'pm' // am/pm
  };
  
  if (/(Y+)/.test(format)) {
    format = format.replace(
      RegExp.$1,
      (d.getFullYear() + '').substr(4 - RegExp.$1.length)
    );
  }
  
  for (let k in o) {
    if (new RegExp('(' + k + ')').test(format)) {
      const len = RegExp.$1.length;
      format = format.replace(
        RegExp.$1,
        k === 'S+' 
          ? o[k].toString().padStart(3, '0').substr(0, len)
          : k === 'A' || k === 'a'
            ? o[k]
            : len === 1
              ? o[k]
              : ('00' + o[k]).substr(('' + o[k]).length)
      );
    }
  }
  
  return format;
}

/**
 * 计算两个日期之间的差值
 * @param {Date|string|number} date1 - 日期1
 * @param {Date|string|number} date2 - 日期2
 * @param {string} [unit='ms'] - 结果单位，可选值：ms(毫秒)、s(秒)、m(分)、h(小时)、d(天)
 * @returns {number} 日期差值
 */
export function dateDiff(date1, date2, unit = 'ms') {
  const d1 = new Date(date1).getTime();
  const d2 = new Date(date2).getTime();
  
  if (isNaN(d1) || isNaN(d2)) return 0;
  
  const diff = Math.abs(d1 - d2);
  
  switch (unit) {
    case 's':
      return Math.floor(diff / 1000);
    case 'm':
      return Math.floor(diff / (1000 * 60));
    case 'h':
      return Math.floor(diff / (1000 * 60 * 60));
    case 'd':
      return Math.floor(diff / (1000 * 60 * 60 * 24));
    case 'ms':
    default:
      return diff;
  }
}

/**
 * 获取相对时间描述
 * @param {Date|string|number} date - 日期
 * @param {Date|string|number} [baseDate=new Date()] - 基准日期，默认为当前时间
 * @returns {string} 相对时间描述
 */
export function relativeTime(date, baseDate = new Date()) {
  const d1 = new Date(date).getTime();
  const d2 = new Date(baseDate).getTime();
  
  if (isNaN(d1)) return '';
  
  const diff = d2 - d1; // 正数表示date在baseDate之前
  const absDiff = Math.abs(diff);
  const isFuture = diff < 0;
  const prefix = isFuture ? '还有' : '';
  const suffix = isFuture ? '' : '前';
  
  if (absDiff < 1000 * 60) {
    // 1分钟内
    return '刚刚';
  } else if (absDiff < 1000 * 60 * 60) {
    // 1小时内
    const mins = Math.floor(absDiff / (1000 * 60));
    return `${prefix}${mins}分钟${suffix}`;
  } else if (absDiff < 1000 * 60 * 60 * 24) {
    // 1天内
    const hours = Math.floor(absDiff / (1000 * 60 * 60));
    return `${prefix}${hours}小时${suffix}`;
  } else if (absDiff < 1000 * 60 * 60 * 24 * 30) {
    // 30天内
    const days = Math.floor(absDiff / (1000 * 60 * 60 * 24));
    return `${prefix}${days}天${suffix}`;
  } else if (absDiff < 1000 * 60 * 60 * 24 * 365) {
    // 1年内
    const months = Math.floor(absDiff / (1000 * 60 * 60 * 24 * 30));
    return `${prefix}${months}个月${suffix}`;
  } else {
    // 1年以上
    const years = Math.floor(absDiff / (1000 * 60 * 60 * 24 * 365));
    return `${prefix}${years}年${suffix}`;
  }
}

/**
 * 获取当前日期所在周的开始和结束日期
 * @param {Date|string|number} [date=new Date()] - 日期
 * @param {number} [weekStart=0] - 一周的开始，0表示周日，1表示周一，以此类推
 * @returns {Object} 包含开始日期和结束日期的对象
 */
export function getWeekRange(date = new Date(), weekStart = 1) {
  const d = new Date(date);
  const day = d.getDay();
  
  // 计算到本周第一天的间隔天数
  const diffToStart = (day + 7 - weekStart) % 7;
  
  // 设置为本周第一天
  const startDate = new Date(d);
  startDate.setDate(d.getDate() - diffToStart);
  startDate.setHours(0, 0, 0, 0);
  
  // 设置为本周最后一天
  const endDate = new Date(startDate);
  endDate.setDate(startDate.getDate() + 6);
  endDate.setHours(23, 59, 59, 999);
  
  return {
    start: startDate,
    end: endDate
  };
}

/**
 * 获取当前日期所在月的开始和结束日期
 * @param {Date|string|number} [date=new Date()] - 日期
 * @returns {Object} 包含开始日期和结束日期的对象
 */
export function getMonthRange(date = new Date()) {
  const d = new Date(date);
  
  // 设置为本月第一天
  const startDate = new Date(d.getFullYear(), d.getMonth(), 1);
  startDate.setHours(0, 0, 0, 0);
  
  // 设置为本月最后一天
  const endDate = new Date(d.getFullYear(), d.getMonth() + 1, 0);
  endDate.setHours(23, 59, 59, 999);
  
  return {
    start: startDate,
    end: endDate
  };
}

export default {
  format: formatDate,
  diff: dateDiff,
  relativeTime,
  getWeekRange,
  getMonthRange
}; 